﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace WenSkin.Controls
{
    [ToolboxBitmap(typeof(ListView))]
    public partial class WenDataListView : ListView, ISupportInitialize
    {
        public WenDataListView()
        {
            InitializeComponent();

            this.View = View.Details;
            this.FullRowSelect = true;
            base.SetStyle(
             //ControlStyles.UserPaint |
             ControlStyles.DoubleBuffer |
             ControlStyles.OptimizedDoubleBuffer |
             ControlStyles.AllPaintingInWmPaint |
             //ControlStyles.ResizeRedraw |
             ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();

            Columns = new WenDataListViewColumnHeaderCollection(this);
            wenColumnHeaders = new List<WenDataListViewColumnHeader>();

            #region 其他方法暂时备注，后续删除
            //Columns.ItemAdded += Columns_ItemAdded;
            //Columns.ItemRemoved += Columns_ItemRemoved;
            #endregion
        }
        public void BeginInit()
        {
            //throw new NotImplementedException();
        }

        public void EndInit()
        {
            itemlistInstance();
            //throw new NotImplementedException();
        }

        #region 其他方法暂时取消
        private void Columns_ItemRemoved(object sender, WenListEventArgs<DataListColumn> e)
        {
            if (base.Columns.Count > 0)
                foreach (ColumnHeader item in base.Columns)
                {
                    if (item.Name == e.Item.Name)
                        base.Columns.Remove(item);
                }
        }

        private void Columns_ItemAdded(object sender, WenListEventArgs<DataListColumn> e)
        {
            base.Columns.Add(e.Item.Text, e.Item.Width);
            //this.Refresh();
            this.Invalidate();
        }
        #endregion

        #region 私有属性
        private object dataSource { get; set; }

        //当前鼠标停留item位置
        private ListViewItem MouseStayItem { get; set; }
        //鼠标停留行的颜色属性
        private Color MouseStayColor { get; set; }
        [Browsable(false)]
        internal List<WenDataListViewColumnHeader> wenColumnHeaders;

        private WenDataListViewItemCollection items;

        #region 项图标

        private ImageList smallImageList { get => itemlist is null ? itemlist = itemlistInstance() : itemlist; }

        private ImageList itemlist;
        private ImageList itemlistInstance()
        {
            ImageList imageList = new ImageList() { ImageSize = ItemIconSize };
            if (ItemIcon != null)
                imageList.Images.Add(ItemIcon);
            else
                imageList.Images.Add(Properties.Resources.itemImage);
            base.SmallImageList = imageList;
            return imageList;
        }
        #endregion

        #endregion

        #region 公有属性


        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        Localizable(true),
        MergableProperty(false)]
        [Category("Wen")]
        [Description("列集合")]
        [RefreshProperties(RefreshProperties.All)]
        public new WenDataListViewColumnHeaderCollection Columns { get; }

        [Browsable(false)]
        public object DataSource
        {
            get => dataSource;
            set
            {
                if (value != null)
                {
                    dataSource = value;
                    DataBind();
                }
            }
        }

        public new ImageList SmallImageList { get => base.SmallImageList ?? smallImageList; set => base.SmallImageList = value; }

        [Category("Wen")]
        [Description("当imagelist无值显示图标")]
        [DefaultValue(null)]
        public Image ItemIcon { get; set; }


        [Category("Wen")]
        [Description("当imagelist 图标大小")]
        [DefaultValue("23,23")]
        public Size ItemIconSize { get; set; } = new Size(23, 23);

        [Category("Wen")]
        [Description("获取包含控件中所有项的集合")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public new WenDataListViewItemCollection Items => items ?? (items = new WenDataListViewItemCollection(this));

        #endregion

        private void DataBind()
        {
            if (dataSource == null)
                return;
            this.Items.Clear();

            IList lists = null;

            if (dataSource is DataSet ds)
            {
                lists = ((IListSource)ds.Tables[0]).GetList();
            }
            else if (dataSource is IListSource listSource)
            {
                lists = listSource.GetList();
            }
            else if (dataSource is IList ilist)
            {
                lists = ilist;
            }


            //绑定数据       
            foreach (var ilist in lists)
            {
                WenDataListViewItem item = new WenDataListViewItem(this)
                {
                    Tag = ilist,
                    ImageIndex = 0
                };
                //if (this.SmallImageList != null)
                //    item.ImageIndex = 0;
                for (int i = 0; i < Columns.Count; i++)
                {
                    if (ilist is DataRowView row)
                    {
                        string value = row[Columns[i].CloumnName]?.ToString();
                        item.Cells.Add(value);
                        if (i == 0)
                            item.Text = value;
                        else
                            item.SubItems.Add(value);
                    }
                    else
                    {
                        List<System.Reflection.PropertyInfo> propertyInfos = new List<System.Reflection.PropertyInfo>(ilist.GetType().GetProperties());
                        string value = propertyInfos.Find(a => a.Name.ToUpper() == Columns[i].CloumnName.ToUpper())?.GetValue(item.Tag, null)?.ToString();

                        item.Cells.Add(value);

                        if (i == 0)
                            item.Text = value;
                        else
                            item.SubItems.Add(value);
                    }
                }
                Items.Add(item);
            }
        }

        #region 项点击事件
        public delegate void ItemClickEventArgs(object serder, ListViewItem item);
        [Category("Wen")]
        [Description("项点击事件")]
        public event ItemClickEventArgs ItemClick;

        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
            var item = GetItemAt(e.X, e.Y);
            ItemClick?.Invoke(this, item);
        }

        #endregion

        #region 多选框勾选事件

        #endregion

        #region 鼠标移动事件 鼠标停留行改变颜色
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            ListViewItem item = this.GetItemAt(e.X, e.Y);
            if (item != null && (item != MouseStayItem || item.BackColor == MouseStayColor))
            {
                if (MouseStayItem != null)
                    MouseStayItem.BackColor = MouseStayColor;
                MouseStayItem = item;
                MouseStayColor = item.BackColor;
                item.BackColor = Color.WhiteSmoke;
            }
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            if (MouseStayItem != null)
                MouseStayItem.BackColor = MouseStayColor;
        }
        #endregion

        #region 标题列信息添加
        public int InsertColumnHeader(int index, WenDataListViewColumnHeader header)
        {
            wenColumnHeaders.Insert(index, header);
            base.Columns.Clear();
            foreach (var item in wenColumnHeaders)
            {
                base.Columns.Add(item);
            }
            return wenColumnHeaders.Count;
        }
        #endregion


    }
    #region 属性类

    [Serializable]
    public class WenDataListViewItem : ListViewItem
    {
        public WenDataListView owner = null;
        public WenDataListViewItem() : base()
        {
        }
        public WenDataListViewItem(WenDataListView owner) : base()
        {
            this.owner = owner;
        }

        protected WenDataListViewItem(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) : base(serializationInfo, streamingContext)
        {
        }

        private WenDataListViewItemCellCollection cells;

        public WenDataListViewItemCellCollection Cells => cells ?? (cells = new WenDataListViewItemCellCollection(this));

    }
    public class WenDataListViewItemCellCollection : IList
    {
        readonly WenDataListViewItem owner = null;
        readonly ArrayList items = new ArrayList();
        public WenDataListViewItemCellCollection(WenDataListViewItem owner)
        {
            this.owner = owner;
        }

        public object this[int index] { get => items[index]; set => items[index] = value; }

        public object this[string value]
        {
            get
            {
                if (owner != null)
                {
                    var aa = owner.owner.wenColumnHeaders;
                    //查找所在的列索引
                    int i = owner.owner.wenColumnHeaders.FindIndex(a => a.CloumnName.ToUpper() == value.ToUpper());
                    if (items.Count > i && i >= 0)
                        return this[i];
                    else
                        return null;
                }
                else
                {
                    return null;
                }
            }
        }
        public bool IsReadOnly => items.IsReadOnly;

        public bool IsFixedSize => items.IsFixedSize;

        public int Count => items.Count;

        public object SyncRoot => items.SyncRoot;

        public bool IsSynchronized => items.IsSynchronized;

        public int Add(object value)
        {
            return items.Add(value);
        }

        public void Clear()
        {
            items.Clear();
        }

        public bool Contains(object value)
        {
            return items.Contains(value);
        }

        public void CopyTo(Array array, int index)
        {
            items.CopyTo(array, index);
        }

        public IEnumerator GetEnumerator()
        {
            return items.GetEnumerator();
        }

        public int IndexOf(object value)
        {
            return items.IndexOf(value);
        }

        public void Insert(int index, object value)
        {
            items.Insert(index, value);
        }

        public void Remove(object value)
        {
            items.Remove(value);
        }

        public void RemoveAt(int index)
        {
            items.RemoveAt(index);
        }
    }

    public class WenDataListViewItemCollection : ListView.ListViewItemCollection
    {
        public object owner = null;
        readonly ArrayList items = new ArrayList();

        public new WenDataListViewItem this[int index] { get => (WenDataListViewItem)items[index]; set { items[index] = value; base[index] = value; } }

        public WenDataListViewItemCollection(WenDataListView owner) : base(owner)
        {
            this.owner = owner;
        }

        public WenDataListViewItemCollection(WenListView owner) : base(owner)
        {
            this.owner = owner;
        }

        public int Add(WenDataListViewItem value)
        {
            base.Add(value);
            return items.Add(value);
        }
        public new WenDataListViewItem Add(ListViewItem value)
        {
            WenDataListViewItem item = new WenDataListViewItem(owner as WenDataListView);
            items.Add(item);
            base.Add(value);
            return item;
        }
        public new WenDataListViewItem Add(string text)
        {
            WenDataListViewItem item = new WenDataListViewItem(owner as WenDataListView) { Text = text, ImageIndex = 0 };
            items.Add(item);
            base.Add(item);
            return item;
        }

        public override void Clear()
        {
            base.Clear();
            items.Clear();
        }

        public void Remove(WenDataListViewItem item)
        {
            base.Remove(item);
            items.Remove(item);
        }
    }

    #endregion
    [ListBindable(false)]
    public class WenDataListViewColumnHeaderCollection : IList
    {
        private readonly WenDataListView owner;
        public WenDataListViewColumnHeaderCollection(WenDataListView owner)
        {
            this.owner = owner ?? throw new NotImplementedException();
        }
        object IList.this[int index] { get => this[index]; set => throw new NotImplementedException(); }

        public WenDataListViewColumnHeader this[int index] { get => this.owner.wenColumnHeaders[index]; }
        public bool IsReadOnly => false;

        public bool IsFixedSize => false;

        public int Count => owner.wenColumnHeaders.Count;

        public object SyncRoot => this;

        public bool IsSynchronized => true;

        public void AddRange(WenDataListViewColumnHeader[] headers)
        {
            foreach (var item in headers)
            {
                Add(item);
            }
        }
        public int Add(object value)
        {
            Insert(Count, value);
            return Count;
        }

        public void Clear()
        {
            owner.wenColumnHeaders.Clear();
        }

        public bool Contains(object value)
        {
            return owner.wenColumnHeaders.Contains((WenDataListViewColumnHeader)value);
        }

        public void CopyTo(Array array, int index)
        {
            owner.wenColumnHeaders.CopyTo((WenDataListViewColumnHeader[])array, index);
        }

        public IEnumerator GetEnumerator()
        {
            return owner.wenColumnHeaders.GetEnumerator();
        }

        public int IndexOf(object value)
        {

            return owner.wenColumnHeaders.IndexOf((WenDataListViewColumnHeader)value);
        }

        public void Insert(int index, object value)
        {
            owner.InsertColumnHeader(index, (WenDataListViewColumnHeader)value);
        }

        public void Remove(object value)
        {
            owner.wenColumnHeaders.Remove((WenDataListViewColumnHeader)value);
        }

        public void RemoveAt(int index)
        {
            owner.wenColumnHeaders.RemoveAt(index);
        }
    }
    public class WenDataListViewColumnHeader : ColumnHeader
    {
        public WenDataListViewColumnHeader() : base()
        {
            CloumnName = "CloumnName";
            Width = 120;
        }
        [DefaultValue("CloumnName")]
        public string CloumnName { get; set; }

        public new string Name { get; set; }
        public override string ToString()
        {
            return string.Format("{0}({1})", Text, CloumnName);
        }
    }
}